package com.knight.hadoop.day07.hdfs;

import java.io.IOException;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.junit.Before;
import org.junit.Test;

public class HdfsClientDemo {

	private FileSystem fs = null;

	@Before
	public void init() throws Exception {
		Configuration conf = new Configuration();
		// conf.set("fs.defaultFS", "hdfs://hadoop4:9000");
		// fs = FileSystem.get(conf);
		// 另外一种构建方式，指定了操作用户名
		fs = FileSystem.get(new URI("hdfs://hadoop4:9000"), conf, "hadoop");
	}

	/**
	 * 上传测试
	 * 
	 * @throws Exception
	 */
	@Test
	public void testUpload() throws Exception {
		fs.copyFromLocalFile(new Path("D://CrackCaptcha.log"), new Path("/access.log"));
		fs.close();
	}

	@Test
	public void testDownload() throws Exception {
		// fs.copyToLocalFile(new Path("/access.log"), new
		// Path("D://access.log"));
		// 不使用本地文件系统下载
		fs.copyToLocalFile(false, new Path("/access.log"), new Path("D://access.log"), true);
		fs.close();
	}

	/**
	 * 测试目录创建 @throws IOException @throws
	 */
	@Test
	public void testMkdir() throws IOException {
		boolean success = fs.mkdirs(new Path("/testMkdir"));
		System.out.println("不带权限的创建:" + success);
	}

	/**
	 * 删除目录
	 * 
	 * @throws IOException
	 * @throws IllegalArgumentException
	 */
	@Test
	public void deleteMkdir() throws IllegalArgumentException, IOException {

		// 是否递归删除
		boolean success = fs.rename(new Path("/testMkdir"), new Path("/rename"));
		System.out.println("删除文件：" + success);

		// 是否递归删除
		success = fs.delete(new Path("/testMkdir"), false);
		System.out.println("删除文件：" + success);
	}
	
	/**
	 * 查看目录下文件的信息
	 * @throws IOException
	 */
	@Test
	public void listFile() throws IOException{
		//返回迭代器对象,为什么要返回迭代器对象
		//因为查看某个目录下的文件，而且是递归查看，如果放入到集合中的话，数据量非常大。会将客户端系统崩溃。
		//使用迭代器的话，没有调用hasNext()方法都单独调用一次，调用next()方法也是同理
		RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
		while(listFiles.hasNext()){
			LocatedFileStatus file = listFiles.next();
			System.out.println("filename:"+file.getPath().getName());
			System.out.println("block size:"+file.getBlockSize());
			System.out.println("permission："+file.getPermission());
			BlockLocation[] blockLocations = file.getBlockLocations();
			for(BlockLocation location : blockLocations){
				String hosts[] = location.getHosts();
				for(String host:hosts){
					System.out.println("dataNode地址："+host);
				}
			}
			System.out.println("-------");
		}
	}
	
	@Test
	public void testListAll() throws Exception{
		FileStatus[] listStatus = fs.listStatus(new Path("/"));
		String isFile = "d--";
		for(FileStatus status : listStatus){
			if(status.isFile()){
				isFile = "f--";
			}else{
				isFile = "d--";
			}
			System.out.println(isFile+status.getPath().getName());
		}
	}
}
